<!DOCTYPE html>
<html>
<head>
    <title>修饰符组合使用演示</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        .combo-demo {
            margin: 20px 0;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .demo-area {
            margin: 15px 0;
            padding: 20px;
            background: #f8f9fa;
            border: 1px solid #dee2e6;
            border-radius: 5px;
            min-height: 100px;
        }
        .nested-area {
            padding: 15px;
            background: #e3f2fd;
            border: 2px solid #2196f3;
            margin: 10px;
        }
        .inner-area {
            padding: 10px;
            background: #fff3e0;
            border: 2px solid #ff9800;
            text-align: center;
        }
        .log-section {
            margin: 15px 0;
            padding: 10px;
            background: #f5f5f5;
            border-radius: 3px;
            max-height: 200px;
            overflow-y: auto;
        }
        .log-item {
            padding: 2px 0;
            font-size: 14px;
            border-bottom: 1px solid #eee;
        }
        .warning {
            color: #d32f2f;
            font-weight: bold;
        }
        .success {
            color: #388e3c;
            font-weight: bold;
        }
        .info {
            color: #1976d2;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div id="app">
        <h2>修饰符组合使用和注意事项</h2>
        
        <!-- 事件修饰符组合 -->
        <div class="combo-demo">
            <h3>事件修饰符组合</h3>
            
            <h4>1. .stop.prevent组合</h4>
            <div class="demo-area" @click="logCombo('外层区域被点击')">
                外层区域
                <a href="https://www.baidu.com" 
                   @click.stop.prevent="logCombo('链接被点击，阻止冒泡和默认行为')"
                   style="color: blue; text-decoration: underline;">
                    点击这个链接（不会跳转，不会冒泡）
                </a>
            </div>
            
            <h4>2. .capture.once组合</h4>
            <div class="nested-area" @click.capture.once="logCombo('外层捕获-只触发一次')">
                外层（捕获阶段，只触发一次）
                <div class="inner-area" @click="logCombo('内层被点击')">
                    内层区域
                </div>
            </div>
            
            <h4>3. .self.prevent组合</h4>
            <form class="demo-area" @submit.self.prevent="logCombo('表单自身被提交')">
                <p>表单区域（只有点击表单背景才会触发）</p>
                <input type="text" placeholder="输入框">
                <button type="submit">提交按钮</button>
            </form>
        </div>
        
        <!-- 键盘修饰符组合 -->
        <div class="combo-demo">
            <h3>键盘修饰符组合</h3>
            
            <h4>复杂快捷键组合</h4>
            <textarea v-model="textContent"
                      @keydown.ctrl.shift.83.prevent="logCombo('Ctrl+Shift+S: 另存为')"
                      @keydown.ctrl.alt.78.prevent="logCombo('Ctrl+Alt+N: 新建窗口')"
                      @keydown.ctrl.shift.90.prevent="logCombo('Ctrl+Shift+Z: 重做')"
                      @keydown.alt.f4.prevent="logCombo('Alt+F4: 关闭窗口（已阻止）')"
                      style="width: 100%; height: 100px; padding: 10px;"
                      placeholder="尝试以下快捷键组合：\nCtrl+Shift+S\nCtrl+Alt+N\nCtrl+Shift+Z\nAlt+F4"></textarea>
            
            <h4>精确匹配示例</h4>
            <input type="text" 
                   v-model="exactInput"
                   @keydown.ctrl.exact="logCombo('只按了Ctrl键')"
                   @keydown.ctrl.shift="logCombo('Ctrl+Shift组合')"
                   @keydown.ctrl.alt="logCombo('Ctrl+Alt组合')"
                   style="width: 100%; padding: 8px; margin: 10px 0;"
                   placeholder="测试精确匹配：只按Ctrl vs Ctrl+其他键">
        </div>
        
        <!-- 修饰符顺序和优先级 -->
        <div class="combo-demo">
            <h3>修饰符顺序和优先级</h3>
            
            <h4>顺序影响结果的示例</h4>
            <div class="demo-area">
                <p class="warning">注意：修饰符的顺序很重要！</p>
                
                <!-- 正确的顺序 -->
                <button @click.stop.prevent="logCombo('正确：先stop再prevent')"
                        style="margin: 5px; padding: 10px;">
                    .stop.prevent（推荐）
                </button>
                
                <!-- 不同的顺序 -->
                <button @click.prevent.stop="logCombo('不同：先prevent再stop')"
                        style="margin: 5px; padding: 10px;">
                    .prevent.stop
                </button>
                
                <!-- 键盘修饰符顺序 -->
                <input type="text"
                       @keydown.shift.ctrl.enter="logCombo('Shift+Ctrl+Enter')"
                       @keydown.ctrl.shift.enter="logCombo('Ctrl+Shift+Enter')"
                       style="width: 300px; padding: 8px; margin: 10px;"
                       placeholder="测试Shift+Ctrl+Enter">
            </div>
        </div>
        
        <!-- 常见错误和注意事项 -->
        <div class="combo-demo">
            <h3>常见错误和注意事项</h3>
            
            <div class="demo-area">
                <h4 class="warning">❌ 常见错误</h4>
                <ul>
                    <li>混淆.self和.stop的作用</li>
                    <li>在不需要的地方使用.prevent</li>
                    <li>键盘修饰符的浏览器兼容性问题</li>
                    <li>过度使用修饰符导致代码难以理解</li>
                </ul>
                
                <h4 class="success">✅ 最佳实践</h4>
                <ul>
                    <li>优先使用Vue修饰符而不是手动调用event方法</li>
                    <li>合理组合修饰符，避免冗余</li>
                    <li>在复杂场景下添加注释说明</li>
                    <li>测试不同浏览器的兼容性</li>
                </ul>
                
                <h4 class="info">💡 性能提示</h4>
                <ul>
                    <li>.once修饰符可以自动移除事件监听器</li>
                    <li>.passive修饰符可以提升滚动性能</li>
                    <li>避免在高频事件上使用复杂的修饰符组合</li>
                </ul>
            </div>
        </div>
        
        <!-- 日志显示 -->
        <div class="log-section">
            <h4>操作日志：</h4>
            <div v-for="log in comboLogs" :key="log.id" class="log-item">
                <span>{{ log.timestamp }}</span> - 
                <span :class="log.type">{{ log.message }}</span>
            </div>
            <button @click="clearComboLogs">清空日志</button>
        </div>
    </div>

    <script>
        const { createApp, ref } = Vue;
        
        createApp({
            setup() {
                const textContent = ref('');
                const exactInput = ref('');
                const comboLogs = ref([]);
                let logId = 1;
                
                const logCombo = (message, type = 'info') => {
                    comboLogs.value.unshift({
                        id: logId++,
                        timestamp: new Date().toLocaleTimeString(),
                        message: message,
                        type: type
                    });
                    
                    if (comboLogs.value.length > 30) {
                        comboLogs.value.pop();
                    }
                    
                    console.log(`[${type.toUpperCase()}] ${message}`);
                };
                
                const clearComboLogs = () => {
                    comboLogs.value = [];
                };
                
                return {
                    textContent,
                    exactInput,
                    comboLogs,
                    logCombo,
                    clearComboLogs
                };
            }
        }).mount('#app');
    </script>
</body>
</html>
